home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / dungeon.c < prev    next >
C/C++ Source or Header  |  1993-01-22  |  39KB  |  1,460 lines

  1. /*    SCCS Id: @(#)dungeon.c    3.1    93/01/17    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "dgn_file.h"
  7.  
  8. #ifdef OVL1
  9.  
  10. #define    DUNGEON_FILE    "dungeon"
  11. #if defined(MICRO) && !defined(AMIGA)
  12. # define RDMODE "rb"
  13. #else
  14. # define RDMODE "r"
  15. #endif
  16.  
  17. #ifdef MULDGN
  18. #define    X_START        "x-start"
  19. #define X_LOCATE    "x-locate"
  20. #define    X_GOAL        "x-goal"
  21. #endif
  22.  
  23. struct proto_dungeon {
  24.     struct    tmpdungeon tmpdungeon[MAXDUNGEON];
  25.     struct    tmplevel   tmplevel[LEV_LIMIT];
  26.     s_level *final_lev[LEV_LIMIT];    /* corresponding level pointers */
  27.     struct    tmpbranch  tmpbranch[BRANCH_LIMIT];
  28.  
  29.     int    start;    /* starting index of current dungeon sp levels */
  30.     int    n_levs;    /* number of tmplevel entries */
  31.     int    n_brs;    /* number of tmpbranch entries */
  32. };
  33.  
  34. int n_dgns;                /* number of dungeons (used here,  */
  35.                     /*   and mklev.c)           */
  36. static branch *branches = (branch *) 0;    /* dungeon branch list           */
  37.  
  38. static void FDECL(Fread, (genericptr_t, int, int, FILE *));
  39. static xchar FDECL(dname_to_dnum, (const char *));
  40. static int FDECL(find_branch, (const char *, struct proto_dungeon *));
  41. static xchar FDECL(parent_dnum, (const char *, struct proto_dungeon *));
  42. static int FDECL(level_range, (XCHAR_P,int,int,int,struct proto_dungeon *,int *));
  43. static xchar FDECL(parent_dlevel, (const char *, struct proto_dungeon *));
  44. static int FDECL(correct_branch_type, (struct tmpbranch *));
  45. static branch *FDECL(add_branch, (int, int, struct proto_dungeon *));
  46. static void FDECL(add_level, (s_level *));
  47. static void FDECL(init_level, (int,int,struct proto_dungeon *));
  48. static int FDECL(possible_places, (int, boolean *, struct proto_dungeon *));
  49. static xchar FDECL(pick_level, (boolean *, int));
  50. static boolean FDECL(place_level, (int, struct proto_dungeon *));
  51. #ifdef WIZARD
  52. static const char *FDECL(br_string, (int));
  53. static void FDECL(print_branch, (winid, int, int, int));
  54. #endif
  55.  
  56. #ifdef DEBUG
  57. #define DD    dungeons[i]
  58. static void NDECL(dumpit);
  59.  
  60. static void
  61. dumpit()
  62. {
  63.     int    i;
  64.     s_level    *x;
  65.     branch *br;
  66.  
  67.     for(i = 0; i < n_dgns; i++)  {
  68.         fprintf(stderr, "\n#%d \"%s\" (%s):\n", i,
  69.                 DD.dname, DD.proto);
  70.         fprintf(stderr, "    num_dunlevs %d, dunlev_ureached %d\n",
  71.                 DD.num_dunlevs, DD.dunlev_ureached);
  72.         fprintf(stderr, "    depth_start %d, ledger_start %d\n",
  73.                 DD.depth_start, DD.ledger_start);
  74.         fprintf(stderr, "    flags:%s%s%s\n",
  75.             DD.flags.rogue_like ? " rogue_like" : "",
  76.             DD.flags.maze_like  ? " maze_like"  : "",
  77.             DD.flags.hellish    ? " hellish"    : "");
  78.         getchar();
  79.     }
  80.     fprintf(stderr,"\nSpecial levels:\n");
  81.     for(x = sp_levchn; x; x = x->next) {
  82.         fprintf(stderr, "%s (%d): ", x->proto, x->rndlevs);
  83.         fprintf(stderr, "on %d, %d; ", x->dlevel.dnum, x->dlevel.dlevel);
  84.         fprintf(stderr, "flags:%s%s%s%s\n",
  85.             x->flags.rogue_like    ? " rogue_like" : "",
  86.             x->flags.maze_like  ? " maze_like"  : "",
  87.             x->flags.hellish    ? " hellish"    : "",
  88.             x->flags.town       ? " town"       : "");
  89.         getchar();
  90.     }
  91.     fprintf(stderr,"\nBranches:\n");
  92.     for (br = branches; br; br = br->next) {
  93.         fprintf(stderr, "%d: %s, end1 %d %d, end2 %d %d, %s\n",
  94.         br->id,
  95.         br->type == BR_STAIR ? "stair" :
  96.             br->type == BR_NO_END1 ? "no end1" :
  97.             br->type == BR_NO_END2 ? "no end2" :
  98.             br->type == BR_PORTAL  ? "portal"  :
  99.                          "unknown",
  100.         br->end1.dnum, br->end1.dlevel,
  101.         br->end2.dnum, br->end2.dlevel,
  102.         br->end1_up ? "end1 up" : "end1 down");
  103.     }
  104.     getchar();
  105.     fprintf(stderr,"\nDone\n");
  106.     getchar();
  107. }
  108. #endif
  109.  
  110. /* Save the dungeon structures. */
  111. void
  112. save_dungeon(fd)
  113.     int fd;
  114. {
  115.     branch *curr;
  116.     int    count;
  117.  
  118.     bwrite(fd, (genericptr_t) &n_dgns, sizeof(n_dgns));
  119.     bwrite(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns);
  120.     bwrite(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology);
  121.     bwrite(fd, (genericptr_t) tune, sizeof tune);
  122.  
  123.     for (count = 0, curr = branches; curr; curr = curr->next)
  124.     count++;
  125.  
  126.     bwrite(fd, (genericptr_t) &count, sizeof(count));
  127.     for (curr = branches; curr; curr = curr->next)
  128.     bwrite(fd, (genericptr_t) curr, sizeof(branch));
  129. }
  130.  
  131. /* Restore the dungeon structures. */
  132. void
  133. restore_dungeon(fd)
  134.     int fd;
  135. {
  136.     branch *curr, *last;
  137.     int    count, i;
  138.  
  139.     mread(fd, (genericptr_t) &n_dgns, sizeof(n_dgns));
  140.     mread(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns);
  141.     mread(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology);
  142.     mread(fd, (genericptr_t) tune, sizeof tune);
  143.  
  144.     last = branches = (branch *) 0;
  145.  
  146.     mread(fd, (genericptr_t) &count, sizeof(count));
  147.     for (i = 0; i < count; i++) {
  148.     curr = (branch *) alloc(sizeof(branch));
  149.     mread(fd, (genericptr_t) curr, sizeof(branch));
  150.     curr->next = (branch *) 0;
  151.     if (last)
  152.         last->next = curr;
  153.     else
  154.         branches = curr;
  155.     last = curr;
  156.     }
  157. }
  158.  
  159. static void
  160. Fread(ptr, size, nitems, stream)
  161.     genericptr_t    ptr;
  162.     int    size, nitems;
  163.     FILE    *stream;
  164. {
  165.     int cnt;
  166.  
  167.     if((cnt = fread(ptr, size, nitems, stream)) != nitems) {
  168.  
  169.         panic("PREMATURE EOF ON DUNGEON DESCRIPTION FILE!\nExpected %d bytes - got %d\n",
  170.             (size * nitems), (size * cnt));
  171.         terminate(1);
  172.     }
  173. }
  174.  
  175. static xchar
  176. dname_to_dnum(s)
  177. const char    *s;
  178. {
  179.     xchar    i;
  180.  
  181.     for (i = 0; i < n_dgns; i++)
  182.         if (!strcmp(dungeons[i].dname, s)) return i;
  183.  
  184.     panic("Couldn't resolve dungeon number for name \"%s\".", s);
  185. #if defined(LINT) || defined(GCC_WARN)
  186.     return (xchar)0;
  187. #endif
  188. }
  189.  
  190. s_level *
  191. find_level(s)
  192.     const char *s;
  193. {
  194.     s_level *curr;
  195.     for(curr = sp_levchn; curr; curr = curr->next)
  196.         if(!strcmp(s, curr->proto)) break;
  197.     return curr;
  198. }
  199.  
  200. /* Find the branch that links the named dungeon. */
  201. static int
  202. find_branch(s, pd)
  203.     const char *s;        /* dungeon name */
  204.     struct proto_dungeon *pd;
  205. {
  206.     int i;
  207.     for (i = 0; i < pd->n_brs; i++)
  208.         if (!strcmp(pd->tmpbranch[i].name, s)) break;
  209.     if (i == pd->n_brs) panic("find_branch: can't find %s", s);
  210.     return i;
  211. }
  212.  
  213.  
  214. /*
  215.  * Find the "parent" by searching the prototype branch list for the branch
  216.  * listing, then figuring out to which dungeon it belongs.
  217.  */
  218. static xchar
  219. parent_dnum(s, pd)
  220. const char       *s;    /* dungeon name */
  221. struct proto_dungeon *pd;
  222. {
  223.     int    i;
  224.     xchar    pdnum;
  225.  
  226.     i = find_branch(s, pd);
  227.     /*
  228.      * Got branch, now find parent dungeon.  Stop if we have reached
  229.      * "this" dungeon (if we haven't found it by now it is an error).
  230.      */
  231.     for (pdnum = 0; strcmp(pd->tmpdungeon[pdnum].name, s); pdnum++)
  232.         if ((i -= pd->tmpdungeon[pdnum].branches) < 0)
  233.         return(pdnum);
  234.  
  235.     panic("parent_dnum: couldn't resolve branch.");
  236. #if defined(LINT) || defined(GCC_WARN)
  237.     return (xchar)0;
  238. #endif
  239. }
  240.  
  241. /*
  242.  * Return a starting point and number of successive positions a level
  243.  * or dungeon entrance can occupy.
  244.  *
  245.  * Note: This follows the acouple (instead of the rcouple) rules for a
  246.  *     negative random component (rand < 0).  These rules are found
  247.  *     in dgn_comp.y.  The acouple [absolute couple] section says that
  248.  *     a negative random component means from the (adjusted) base to the
  249.  *     end of the dungeon.
  250.  */
  251. static int
  252. level_range(dgn, base, rand, chain, pd, adjusted_base)
  253.     xchar    dgn;
  254.     int    base, rand, chain;
  255.     struct proto_dungeon *pd;
  256.     int *adjusted_base;
  257. {
  258.     int lmax = dungeons[dgn].num_dunlevs;
  259.  
  260.     if (chain >= 0) {         /* relative to a special level */
  261.         s_level *levtmp = pd->final_lev[chain];
  262.         if (!levtmp) panic("level_range: empty chain level!");
  263.  
  264.         base += levtmp->dlevel.dlevel;
  265.     } else {            /* absolute in the dungeon */
  266.         /* from end of dungeon */
  267.         if (base < 0) base = (lmax + base + 1);
  268.     }
  269.  
  270.     if (base < 1 || base > lmax)
  271.         panic("level_range: base value out of range");
  272.  
  273.     *adjusted_base = base;
  274.  
  275.     if (rand == -1) {    /* from base to end of dungeon */
  276.         return (lmax - base + 1);
  277.     } else if (rand) {
  278.         /* make sure we don't run off the end of the dungeon */
  279.         return (((base + rand - 1) > lmax) ? lmax-base+1 : rand);
  280.     } /* else only one choice */
  281.     return 1;
  282. }
  283.  
  284. static xchar
  285. parent_dlevel(s, pd)
  286.     const char    *s;
  287.     struct proto_dungeon *pd;
  288. {
  289.     int i, num, base;
  290.  
  291.     i = find_branch(s, pd);
  292.     num = level_range(parent_dnum(s, pd), pd->tmpbranch[i].lev.base,
  293.                           pd->tmpbranch[i].lev.rand,
  294.                           pd->tmpbranch[i].chain,
  295.                           pd, &base);
  296.     return (xchar) rn1(num,base);
  297. }
  298.  
  299. /* Convert from the temporary branch type to the dungeon branch type. */
  300. static int
  301. correct_branch_type(tbr)
  302.     struct tmpbranch *tbr;
  303. {
  304.     switch (tbr->type) {
  305.     case TBR_STAIR:        return BR_STAIR;
  306.     case TBR_NO_UP:        return tbr->up ? BR_NO_END1 : BR_NO_END2;
  307.     case TBR_NO_DOWN:    return tbr->up ? BR_NO_END2 : BR_NO_END1;
  308.     case TBR_PORTAL:    return BR_PORTAL;
  309.     }
  310.     impossible("correct_branch_type: unknown branch type");
  311.     return BR_STAIR;
  312. }
  313.  
  314. /*
  315.  * Add the given branch to the branch list.  The branch list is ordered
  316.  * by end1 dungeon and level followed by end2 dungeon and level.  If
  317.  * extract_first is true, then the branch is already part of the list
  318.  * but needs to be repositioned.
  319.  */
  320. void
  321. insert_branch(new_branch, extract_first)
  322.    branch *new_branch;
  323.    boolean extract_first;
  324. {
  325.     branch *curr, *prev;
  326.     long new_val, curr_val, prev_val;
  327.  
  328.     if (extract_first) {
  329.     for (prev = 0, curr = branches; curr; prev = curr, curr = curr->next)
  330.         if (curr == new_branch) break;
  331.  
  332.     if (!curr) panic("insert_branch: not found");
  333.     if (prev)
  334.         prev->next = curr->next;
  335.     else
  336.         branches = curr->next;
  337.     }
  338.     new_branch->next = (branch *) 0;
  339.  
  340. /* Convert the branch into a unique number so we can sort them. */
  341. #define branch_val(bp) ((((long)(bp)->end1.dnum * (MAXLEVEL+1) + (long)(bp)->end1.dlevel) * (MAXDUNGEON+1) * (MAXLEVEL+1)) + ((long)(bp)->end2.dnum * (MAXLEVEL+1) + (long)(bp)->end2.dlevel))
  342.  
  343.     /*
  344.      * Insert the new branch into the correct place in the branch list.
  345.      */
  346.     prev = (branch *) 0;
  347.     prev_val = -1;
  348.     new_val = branch_val(new_branch);
  349.     for (curr = branches; curr;
  350.             prev_val = curr_val, prev = curr, curr = curr->next) {
  351.     curr_val = branch_val(curr);
  352.     if (prev_val < new_val && new_val <= curr_val) break;
  353.     }
  354.     if (prev) {
  355.     new_branch->next = curr;
  356.     prev->next = new_branch;
  357.     } else {
  358.     new_branch->next = branches;
  359.     branches = new_branch;
  360.     }
  361. }
  362.  
  363. /* Add a dungeon branch to the branch list. */
  364. static branch *
  365. add_branch(dgn, child_entry_level, pd)
  366.     int dgn;
  367.     int child_entry_level;
  368.     struct proto_dungeon *pd;
  369. {
  370.     static int branch_id = 0;
  371.     int branch_num;
  372.     branch *new_branch;
  373.  
  374.     branch_num = find_branch(dungeons[dgn].dname,pd);
  375.     new_branch = (branch *) alloc(sizeof(branch));
  376.     new_branch->next = (branch *) 0;
  377.     new_branch->id = branch_id++;
  378.     new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]);
  379.     new_branch->end1.dnum = parent_dnum(dungeons[dgn].dname, pd);
  380.     new_branch->end1.dlevel = parent_dlevel(dungeons[dgn].dname, pd);
  381.     new_branch->end2.dnum = dgn;
  382.     new_branch->end2.dlevel = child_entry_level;
  383.     new_branch->end1_up = pd->tmpbranch[branch_num].up ? TRUE : FALSE;
  384.  
  385.     insert_branch(new_branch, FALSE);
  386.     return new_branch;
  387. }
  388.  
  389. /*
  390.  * Add new level to special level chain.  Insert it in level order with the
  391.  * other levels in this dungeon.  This assumes that we are never given a
  392.  * level that has a dungeon number less than the dungeon number of the
  393.  * last entry.
  394.  */
  395. static void
  396. add_level(new_lev)
  397.     s_level *new_lev;
  398. {
  399.     s_level *prev, *curr;
  400.  
  401.     prev = (s_level *) 0;
  402.     for (curr = sp_levchn; curr; curr = curr->next) {
  403.         if (curr->dlevel.dnum == new_lev->dlevel.dnum &&
  404.             curr->dlevel.dlevel > new_lev->dlevel.dlevel)
  405.         break;
  406.         prev = curr;
  407.     }
  408.     if (!prev) {
  409.         new_lev->next = sp_levchn;
  410.         sp_levchn = new_lev;
  411.     } else {
  412.         new_lev->next = curr;
  413.         prev->next = new_lev;
  414.     }
  415. }
  416.  
  417. static void
  418. init_level(dgn, proto_index, pd)
  419.     int dgn, proto_index;
  420.     struct proto_dungeon *pd;
  421. {
  422.     s_level    *new_level;
  423.     struct tmplevel *tlevel = &pd->tmplevel[proto_index];
  424.  
  425.     pd->final_lev[proto_index] = (s_level *) 0; /* no "real" level */
  426. #ifdef WIZARD
  427.     if (!wizard)
  428. #endif
  429.         if (tlevel->chance <= rn2(100)) return;
  430.  
  431.     pd->final_lev[proto_index] = new_level =
  432.                     (s_level *) alloc(sizeof(s_level));
  433.     /* load new level with data */
  434.     Strcpy(new_level->proto, tlevel->name);
  435.     new_level->boneid = tlevel->boneschar;
  436.     new_level->dlevel.dnum = dgn;
  437.     new_level->dlevel.dlevel = 0;    /* for now */
  438.  
  439.     new_level->flags.town = !!(tlevel->flags & TOWN);
  440.     new_level->flags.hellish = !!(tlevel->flags & HELLISH);
  441.     new_level->flags.maze_like = !!(tlevel->flags & MAZELIKE);
  442.     new_level->flags.rogue_like = !!(tlevel->flags & ROGUELIKE);
  443.     new_level->flags.align = ((tlevel->flags & D_ALIGN_MASK) >> 4);
  444.  
  445.     new_level->rndlevs = tlevel->rndlevs;
  446.     new_level->next    = (s_level *) 0;
  447. }
  448.  
  449. static int
  450. possible_places(idx, map, pd)
  451.     int idx;        /* prototype index */
  452.     boolean *map;    /* array MAXLEVEL+1 in length */
  453.     struct proto_dungeon *pd;
  454. {
  455.     int i, start, count;
  456.     s_level *lev = pd->final_lev[idx];
  457.  
  458.     /* init level possibilities */
  459.     for (i = 0; i <= MAXLEVEL; i++) map[i] = FALSE;
  460.  
  461.     /* get base and range and set those entried to true */
  462.     count = level_range(lev->dlevel.dnum, pd->tmplevel[idx].lev.base,
  463.                     pd->tmplevel[idx].lev.rand,
  464.                     pd->tmplevel[idx].chain,
  465.                     pd, &start);
  466.     for (i = start; i < start+count; i++)
  467.     map[i] = TRUE;
  468.  
  469.     /* mark off already placed levels */
  470.     for (i = pd->start; i < idx; i++) {
  471.     if (pd->final_lev[i] && map[pd->final_lev[i]->dlevel.dlevel]) {
  472.         map[pd->final_lev[i]->dlevel.dlevel] = FALSE;
  473.         --count;
  474.     }
  475.     }
  476.  
  477.     return count;
  478. }
  479.  
  480. /* Pick the nth TRUE entry in the given boolean array. */
  481. static xchar
  482. pick_level(map, nth)
  483.     boolean *map;    /* an array MAXLEVEL+1 in size */
  484.     int nth;
  485. {
  486.     int i;
  487.     for (i = 1; i <= MAXLEVEL; i++)
  488.     if (map[i] && !nth--) return (xchar) i;
  489.     panic("pick_level:  ran out of valid levels");
  490.     return 0;
  491. }
  492.  
  493. #ifdef DDEBUG
  494. static void FDECL(indent,(int));
  495.  
  496. static void
  497. indent(d)
  498. int d;
  499. {
  500.     while (d-- > 0) fputs("    ", stderr);
  501. }
  502. #endif
  503.  
  504. /*
  505.  * Place a level.  First, find the possible places on a dungeon map
  506.  * template.  Next pick one.  Then try to place the next level.  If
  507.  * sucessful, we're done.  Otherwise, try another (and another) until
  508.  * all possible places have been tried.  If all possible places have
  509.  * been exausted, return false.
  510.  */
  511. static boolean
  512. place_level(proto_index, pd)
  513.     int proto_index;
  514.     struct proto_dungeon *pd;
  515. {
  516.     boolean map[MAXLEVEL+1];    /* valid levels are 1..MAXLEVEL inclusive */
  517.     s_level *lev;
  518.     int npossible;
  519. #ifdef DDEBUG
  520.     int i;
  521. #endif
  522.  
  523.     if (proto_index == pd->n_levs) return TRUE;    /* at end of proto levels */
  524.  
  525.     lev = pd->final_lev[proto_index];
  526.  
  527.     /* No level created for this prototype, goto next. */
  528.     if (!lev) return place_level(proto_index+1, pd);
  529.  
  530.     npossible = possible_places(proto_index, map, pd);
  531.  
  532.     for (; npossible; --npossible) {
  533.     lev->dlevel.dlevel = pick_level(map, rn2(npossible));
  534. #ifdef DDEBUG
  535.     indent(proto_index-pd->start);
  536.     fprintf(stderr,"%s: trying %d [ ", lev->proto, lev->dlevel.dlevel);
  537.     for (i = 1; i <= MAXLEVEL; i++)
  538.         if (map[i]) fprintf(stderr,"%d ", i);
  539.     fprintf(stderr,"]\n");
  540. #endif
  541.     if (place_level(proto_index+1, pd)) return TRUE;
  542.     map[lev->dlevel.dlevel] = FALSE;    /* this choice didn't work */
  543.     }
  544. #ifdef DDEBUG
  545.     indent(proto_index-pd->start);
  546.     fprintf(stderr,"%s: failed\n", lev->proto);
  547. #endif
  548.     return FALSE;
  549. }
  550.  
  551. void
  552. init_dungeons()        /* initialize the "dungeon" structs */
  553. {
  554.     FILE    *dgn_file;
  555.     register int i, cl = 0, cb = 0;
  556.     register s_level *x;
  557.     struct proto_dungeon pd;
  558.  
  559.     pd.n_levs = pd.n_brs = 0;
  560.  
  561.     dgn_file = fopen_datafile(DUNGEON_FILE, RDMODE);
  562.     if (!dgn_file)
  563.         panic("\rCANNOT OPEN DUNGEON DESCRIPTION FILE %s.", DUNGEON_FILE);
  564.  
  565.     /*
  566.      * Read in each dungeon and transfer the results to the internal
  567.      * dungeon arrays.
  568.      */
  569.     sp_levchn = (s_level *) 0;
  570.     Fread((genericptr_t)&n_dgns, sizeof(int), 1, dgn_file);
  571.     if (n_dgns >= MAXDUNGEON)
  572.         panic("init_dungeons: too many dungeons");
  573.  
  574.     for (i = 0; i < n_dgns; i++) {
  575.         Fread((genericptr_t)&pd.tmpdungeon[i],
  576.                     sizeof(struct tmpdungeon), 1, dgn_file);
  577. #ifdef WIZARD
  578.         if(!wizard)
  579. #endif
  580.           if(pd.tmpdungeon[i].chance && (pd.tmpdungeon[i].chance <= rn2(100))) {
  581.         int j;
  582.  
  583.         /* skip over any levels or branches */
  584.         for(j = 0; j < pd.tmpdungeon[i].levels; j++)
  585.             Fread((genericptr_t)&pd.tmplevel[cl], sizeof(struct tmplevel),
  586.                             1, dgn_file);
  587.  
  588.         for(j = 0; j < pd.tmpdungeon[i].branches; j++)
  589.             Fread((genericptr_t)&pd.tmpbranch[cb],
  590.                     sizeof(struct tmpbranch), 1, dgn_file);
  591.         n_dgns--; i--;
  592.         continue;
  593.           }
  594.  
  595.         Strcpy(dungeons[i].dname, pd.tmpdungeon[i].name);
  596.         Strcpy(dungeons[i].proto, pd.tmpdungeon[i].protoname);
  597.         dungeons[i].boneid = pd.tmpdungeon[i].boneschar;
  598.  
  599.         if(pd.tmpdungeon[i].lev.rand)
  600.         dungeons[i].num_dunlevs = rn1(pd.tmpdungeon[i].lev.rand,
  601.                           pd.tmpdungeon[i].lev.base);
  602.         else dungeons[i].num_dunlevs = pd.tmpdungeon[i].lev.base;
  603.  
  604.         if(!i) {
  605.         dungeons[i].ledger_start = 0;
  606.         dungeons[i].depth_start = 1;
  607.         dungeons[i].dunlev_ureached = 1;
  608.         } else {
  609.         dungeons[i].ledger_start = dungeons[i-1].ledger_start +
  610.                           dungeons[i-1].num_dunlevs;
  611.         dungeons[i].dunlev_ureached = 0;
  612.         }
  613.  
  614.         dungeons[i].flags.hellish = !!(pd.tmpdungeon[i].flags & HELLISH);
  615.         dungeons[i].flags.maze_like = !!(pd.tmpdungeon[i].flags & MAZELIKE);
  616.         dungeons[i].flags.rogue_like = !!(pd.tmpdungeon[i].flags & ROGUELIKE);
  617.         dungeons[i].flags.align = ((pd.tmpdungeon[i].flags & D_ALIGN_MASK) >> 4);
  618.         /*
  619.          * Set the entry level for this dungeon.  The pd.tmpdungeon entry
  620.          * value means:
  621.          *        < 0    from bottom (-1 == bottom level)
  622.          *          0    default (top)
  623.          *        > 0    actual level (1 = top)
  624.          *
  625.          * Note that the entry_lev field in the dungeon structure is
  626.          * redundant.  It is used only here and in print_dungeon().
  627.          */
  628.         if (pd.tmpdungeon[i].entry_lev < 0) {
  629.         dungeons[i].entry_lev = dungeons[i].num_dunlevs +
  630.                         pd.tmpdungeon[i].entry_lev + 1;
  631.         if (dungeons[i].entry_lev <= 0) dungeons[i].entry_lev = 1;
  632.         } else if (pd.tmpdungeon[i].entry_lev > 0) {
  633.         dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev;
  634.         if (dungeons[i].entry_lev > dungeons[i].num_dunlevs)
  635.             dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev;
  636.         } else { /* default */
  637.         dungeons[i].entry_lev = 1;    /* defaults to top level */
  638.         }
  639.  
  640.         if (i) {    /* set depth */
  641.         branch *br;
  642.         xchar from_depth;
  643.         boolean from_up;
  644.  
  645.         br = add_branch(i, dungeons[i].entry_lev, &pd);
  646.  
  647.         /* Get the depth of the connecting end. */
  648.         if (br->end1.dnum == i) {
  649.             from_depth = depth(&br->end2);
  650.             from_up = !br->end1_up;
  651.         } else {
  652.             from_depth = depth(&br->end1);
  653.             from_up = br->end1_up;
  654.         }
  655.  
  656.         /*
  657.          * Calculate the depth of the top of the dungeon via
  658.          * its branch.  First, the depth of the entry point:
  659.          *
  660.          *    depth of branch from "parent" dungeon
  661.          *    + -1 or 1 depending on a up or down stair or
  662.          *      0 if portal
  663.          *
  664.          * Followed by the depth of the top of the dungeon:
  665.          *
  666.          *    - (entry depth - 1)
  667.          *
  668.          * We'll say that portals stay on the same depth.
  669.          */
  670.         dungeons[i].depth_start = from_depth
  671.                     + (br->type == BR_PORTAL ? 0 :
  672.                             (from_up ? -1 : 1))
  673.                     - (dungeons[i].entry_lev - 1);
  674.         }
  675.  
  676.         /* this is redundant - it should have been flagged by dgn_comp */
  677.         if(dungeons[i].num_dunlevs > MAXLEVEL)
  678.         dungeons[i].num_dunlevs = MAXLEVEL;
  679.  
  680.         pd.start = pd.n_levs;    /* save starting point */
  681.         pd.n_levs += pd.tmpdungeon[i].levels;
  682.         if (pd.n_levs > LEV_LIMIT)
  683.         panic("init_dungeon: too many special levels");
  684.         /*
  685.          * Read in the prototype special levels.  Don't add generated
  686.          * special levels until they are all placed.
  687.          */
  688.         for(; cl < pd.n_levs; cl++) {
  689.         Fread((genericptr_t)&pd.tmplevel[cl],
  690.                     sizeof(struct tmplevel), 1, dgn_file);
  691.         init_level(i, cl, &pd);
  692.         }
  693.         /*
  694.          * Recursively place the generated levels for this dungeon.  This
  695.          * routine will attempt all possible combinations before giving
  696.          * up.
  697.          */
  698.         if (!place_level(pd.start, &pd))
  699.         panic("init_dungeon:  couldn't place levels");
  700. #ifdef DDEBUG
  701.         fprintf(stderr, "--- end of dungeon %d ---\n", i);
  702.         fflush(stderr);
  703.         getchar();
  704. #endif
  705.         for (; pd.start < pd.n_levs; pd.start++)
  706.         if (pd.final_lev[pd.start]) add_level(pd.final_lev[pd.start]);
  707.  
  708.  
  709.         pd.n_brs += pd.tmpdungeon[i].branches;
  710.         if (pd.n_brs > BRANCH_LIMIT)
  711.         panic("init_dungeon: too many branches");
  712.         for(; cb < pd.n_brs; cb++)
  713.         Fread((genericptr_t)&pd.tmpbranch[cb],
  714.                     sizeof(struct tmpbranch), 1, dgn_file);
  715.     }
  716.     (void) fclose(dgn_file);
  717.  
  718.     for (i = 0; i < 5; i++) tune[i] = 'A' + rn2(7);
  719.     tune[5] = 0;
  720.  
  721.     /*
  722.      * Find most of the special levels and dungeons so we can access their
  723.      * locations quickly.
  724.      */
  725. #ifdef REINCARNATION
  726.     if ((x = find_level("rogue")) != 0)
  727.         assign_level(&rogue_level, &x->dlevel);
  728. #endif
  729.     if ((x = find_level("oracle")) != 0)
  730.         assign_level(&oracle_level, &x->dlevel);
  731.     if ((x = find_level("bigroom")) != 0)
  732.         assign_level(&bigroom_level, &x->dlevel);
  733.     if ((x = find_level("medusa")) != 0)
  734.         assign_level(&medusa_level, &x->dlevel);
  735.     if ((x = find_level("castle")) != 0)
  736.         assign_level(&stronghold_level, &x->dlevel);
  737.     if ((x = find_level("valley")) != 0)
  738.         assign_level(&valley_level, &x->dlevel);
  739.     if ((x = find_level("wizard1")) != 0)
  740.         assign_level(&wiz1_level, &x->dlevel);
  741.     if ((x = find_level("wizard2")) != 0)
  742.         assign_level(&wiz2_level, &x->dlevel);
  743.     if ((x = find_level("wizard3")) != 0)
  744.         assign_level(&wiz3_level, &x->dlevel);
  745.     if ((x = find_level("juiblex")) != 0)
  746.         assign_level(&juiblex_level, &x->dlevel);
  747.     if ((x = find_level("orcus")) != 0)
  748.         assign_level(&orcus_level, &x->dlevel);
  749.     if ((x = find_level("asmodeus")) != 0)
  750.         assign_level(&asmodeus_level, &x->dlevel);
  751.     if ((x = find_level("baalz")) != 0)
  752.         assign_level(&baalzebub_level, &x->dlevel);
  753.     if ((x = find_level("fakewiz1")) != 0)
  754.         assign_level(&portal_level, &x->dlevel);
  755.     if ((x = find_level("sanctum")) != 0)
  756.         assign_level(&sanctum_level, &x->dlevel);
  757.     if ((x = find_level("earth")) != 0)
  758.         assign_level(&earth_level, &x->dlevel);
  759.     if ((x = find_level("water")) != 0)
  760.         assign_level(&water_level, &x->dlevel);
  761.     if ((x = find_level("fire")) != 0)
  762.         assign_level(&fire_level, &x->dlevel);
  763.     if ((x = find_level("air")) != 0)
  764.         assign_level(&air_level, &x->dlevel);
  765.     if ((x = find_level("astral")) != 0)
  766.         assign_level(&astral_level, &x->dlevel);
  767. #ifdef MULDGN
  768.     if ((x = find_level("knox")) != 0) {
  769.         branch *br;
  770.         assign_level(&knox_level, &x->dlevel);
  771.         /*
  772.          * Kludge to allow floating Knox entrance.  We specify a floating
  773.          * entrance by the fact that it's entrance (end1) has a bogus dnum,
  774.          * namely n_dgns.
  775.          */
  776.         for (br = branches; br; br = br->next)
  777.         if (on_level(&br->end2, &knox_level)) break;
  778.  
  779.         if (br) br->end1.dnum = n_dgns;
  780.         /* adjust the branch's position on the list */
  781.         insert_branch(br, TRUE);
  782.     }
  783. /*
  784.  *    This is where the name substitution on the levels of the quest
  785.  *    dungeon occur.
  786.  */
  787.     if ((x = find_level(X_START)) != 0) {
  788.         x->proto[0] = pl_character[0];
  789.         assign_level(&qstart_level, &x->dlevel);
  790.     }
  791.     if ((x = find_level(X_LOCATE)) != 0) {
  792.         x->proto[0] = pl_character[0];
  793.         assign_level(&qlocate_level, &x->dlevel);
  794.     }
  795.     if ((x = find_level(X_GOAL)) != 0) {
  796.         x->proto[0] = pl_character[0];
  797.         assign_level(&nemesis_level, &x->dlevel);
  798.     }
  799. /*
  800.  *    I hate hardwiring these names. :-(
  801.  */
  802.     quest_dnum = dname_to_dnum("The Quest");
  803.     mines_dnum = dname_to_dnum("The Gnomish Mines");
  804. #endif
  805.     tower_dnum = dname_to_dnum("Vlad's Tower");
  806.  
  807. #ifdef DEBUG
  808.     dumpit();
  809. #endif
  810. }
  811.  
  812. xchar
  813. dunlev(lev)    /* return the level number for lev in *this* dungeon */
  814. d_level    *lev;
  815. {
  816.     return(lev->dlevel);
  817. }
  818.  
  819. xchar
  820. dunlevs_in_dungeon(lev)    /* return the lowest level number for *this* dungeon*/
  821. d_level    *lev;
  822. {
  823.     return(dungeons[lev->dnum].num_dunlevs);
  824. }
  825.  
  826. xchar
  827. deepest_lev_reached(noquest) /* return the lowest level explored in the game*/
  828. boolean noquest;
  829. {
  830.     /* this function is used for three purposes: to provide a factor
  831.      * of difficulty in monster generation; to provide a factor of
  832.      * difficulty in experience calculations (botl.c and end.c); and
  833.      * to insert the deepest level reached in the game in the topten
  834.      * display.  the 'noquest' arg switch is required for the latter.
  835.      *
  836.      * from the player's point of view, going into the Quest is _not_
  837.      * going deeper into the dungeon -- it is going back "home", where
  838.      * the dungeon starts at level 1.  given the setup in dungeon.def,
  839.      * the depth of the Quest (thought of as starting at level 1) is
  840.      * never lower than the level of entry into the Quest, so we exclude
  841.      * the Quest from the topten "deepest level reached" display
  842.      * calculation.  _However_ the Quest is a difficult dungeon, so we
  843.      * include it in the factor of difficulty calculations.
  844.      */
  845.     register int i;
  846.     d_level tmp;
  847.     register xchar ret = 0;
  848.  
  849.     for(i = 0; i < n_dgns; i++) {
  850.         if((tmp.dlevel = dungeons[i].dunlev_ureached) == 0) continue;
  851.         if(!strcmp(dungeons[i].dname, "The Quest") && noquest) continue;
  852.  
  853.         tmp.dnum = i;
  854.         if(depth(&tmp) > ret) ret = depth(&tmp);
  855.     }
  856.     return(ret);
  857. }
  858.  
  859. /* return a bookkeeping level number for purpose of comparisons and
  860.  * save/restore */
  861. xchar
  862. ledger_no(lev)
  863. d_level    *lev;
  864. {
  865.     return(lev->dlevel + dungeons[lev->dnum].ledger_start);
  866. }
  867.  
  868. /*
  869.  * The last level in the bookkeeping list of level is the bottom of the last
  870.  * dungeon in the dungeons[] array.
  871.  *
  872.  * Maxledgerno() -- which is the max number of levels in the bookkeeping
  873.  * list, should not be confused with dunlevs_in_dungeon(lev) -- which
  874.  * returns the max number of levels in lev's dungeon, and both should
  875.  * not be confused with deepest_lev_reached() -- which returns the lowest
  876.  * depth visited by the player.
  877.  */
  878. xchar
  879. maxledgerno()
  880. {
  881.     return (xchar) (dungeons[n_dgns-1].ledger_start +
  882.                 dungeons[n_dgns-1].num_dunlevs);
  883. }
  884.  
  885. /* return the dungeon that this ledgerno exists in */
  886. xchar
  887. ledger_to_dnum(ledgerno)
  888. xchar    ledgerno;
  889. {
  890.     xchar    i;
  891.  
  892.     for(i = 0; i < n_dgns; i++)
  893.         if(dungeons[i].ledger_start >= ledgerno) return(i-1);
  894.  
  895.     return(MAXDUNGEON);
  896. }
  897.  
  898. /* return the level of the dungeon this ledgerno exists in */
  899. xchar
  900. ledger_to_dlev(ledgerno)
  901. xchar    ledgerno;
  902. {
  903.     return(ledgerno - dungeons[ledger_to_dnum(ledgerno)].ledger_start);
  904. }
  905.  
  906. #endif /* OVL1 */
  907. #ifdef OVL0
  908.  
  909. /* returns the depth of a level, in floors below the surface    */
  910. /* (note levels in different dungeons can have the same depth).    */
  911. xchar
  912. depth(lev)
  913. d_level    *lev;
  914. {
  915.     return dungeons[lev->dnum].depth_start + lev->dlevel - 1;
  916. }
  917.  
  918. boolean
  919. on_level(lev1, lev2)    /* are "lev1" and "lev2" actually the same? */
  920. d_level    *lev1, *lev2;
  921. {
  922.     return((lev1->dnum == lev2->dnum) && (lev1->dlevel == lev2->dlevel));
  923. }
  924.  
  925. #endif /* OVL0 */
  926. #ifdef OVL1
  927.  
  928. s_level *
  929. /* is this level referenced in the special level chain? */
  930. Is_special(lev)
  931. d_level    *lev;
  932. {
  933.     s_level *levtmp;
  934.  
  935.     for (levtmp = sp_levchn; levtmp; levtmp = levtmp->next)
  936.         if (on_level(lev, &levtmp->dlevel)) return(levtmp);
  937.  
  938.     return((s_level *)0);
  939. }
  940.  
  941. /*
  942.  * Is this a multi-dungeon branch level?  If so, return a pointer to the
  943.  * branch.  Otherwise, return NULL.
  944.  */
  945. branch *
  946. Is_branchlev(lev)
  947.     d_level    *lev;
  948. {
  949.     branch *curr;
  950.  
  951.     for (curr = branches; curr; curr = curr->next) {
  952.         if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2))
  953.         return curr;
  954.     }
  955.     return (branch *) 0;
  956. }
  957.  
  958. /* goto the next level (or appropriate dungeon) */
  959. void
  960. next_level(at_stairs )
  961. boolean    at_stairs;
  962. {
  963.     if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) {
  964.         /* Taking a down dungeon branch. */
  965.         goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
  966.     } else {
  967.         /* Going down a stairs or jump in a trap door. */
  968.         d_level    newlevel;
  969.  
  970.         newlevel.dnum = u.uz.dnum;
  971.         newlevel.dlevel = u.uz.dlevel + 1;
  972.         goto_level(&newlevel, at_stairs, !at_stairs, FALSE);
  973.     }
  974. }
  975.  
  976. /* goto the previous level (or appropriate dungeon) */
  977. void
  978. prev_level(at_stairs)
  979. boolean    at_stairs;
  980. {
  981.     if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) {
  982.         /* Taking an up dungeon branch. */
  983.         if(!u.uz.dnum  && !u.uhave.amulet) done(ESCAPED);
  984.         else goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
  985.     } else {
  986.         /* Going up a stairs or rising through the ceiling. */
  987.         d_level    newlevel;
  988.         newlevel.dnum = u.uz.dnum;
  989.         newlevel.dlevel = u.uz.dlevel - 1;
  990.         goto_level(&newlevel, at_stairs, FALSE, FALSE);
  991.     }
  992. }
  993.  
  994. void
  995. u_on_sstairs() {    /* place you on the special staircase */
  996.  
  997.     if (sstairs.sx && sstairs.sy) {
  998.         u.ux = sstairs.sx;
  999.         u.uy = sstairs.sy;
  1000.     } else {
  1001.         /* code stolen from goto_level */
  1002.         int try = 0;
  1003. #ifdef DEBUG
  1004.         pline("u_on_sstairs: picking random spot");
  1005. #endif
  1006. #define badspot(x,y) ((levl[x][y].typ != ROOM && levl[x][y].typ != CORR) || MON_AT(x, y))
  1007.         do {
  1008.         u.ux = rnd(COLNO-1);
  1009.         u.uy = rn2(ROWNO);
  1010.         } while(try++ < 100 && badspot(u.ux, u.uy));
  1011.         if (try >= 100)
  1012.         panic("u_on_sstairs: could not relocate player!");
  1013. #undef badspot
  1014.     }
  1015. }
  1016.  
  1017. void
  1018. u_on_upstairs()    /* place you on upstairs (or special equivalent) */
  1019. {
  1020.     if(xupstair && yupstair)  {
  1021.  
  1022.         u.ux = xupstair;
  1023.         u.uy = yupstair;
  1024.     }
  1025.     else u_on_sstairs();
  1026. }
  1027.  
  1028. void
  1029. u_on_dnstairs()    /* place you on dnstairs (or special equivalent) */
  1030. {
  1031.     if(xdnstair && ydnstair)  {
  1032.  
  1033.         u.ux = xdnstair;
  1034.         u.uy = ydnstair;
  1035.     }
  1036.     else u_on_sstairs();
  1037. }
  1038.  
  1039. boolean
  1040. On_stairs(x, y)
  1041. xchar x, y;
  1042. {
  1043.     return((x == xupstair && y == yupstair) ||
  1044.            (x == xdnstair && y == ydnstair) ||
  1045.            (x == xdnladder && y == ydnladder) ||
  1046.            (x == xupladder && y == yupladder) ||
  1047.            (x == sstairs.sx && y == sstairs.sy));
  1048. }
  1049.  
  1050. boolean
  1051. Is_botlevel(lev)
  1052. d_level *lev;
  1053. {
  1054.     return lev->dlevel == dungeons[lev->dnum].num_dunlevs;
  1055. }
  1056.  
  1057. boolean
  1058. Can_dig_down(lev)
  1059. d_level *lev;
  1060. {
  1061.     return !level.flags.hardfloor
  1062.         && !Is_botlevel(lev) && !Invocation_lev(lev);
  1063. }
  1064.  
  1065. /*
  1066.  * Like Can_dig_down (above), but also allows falling through on the
  1067.  * stronghold level.  Normally, the bottom level of a dungeon resists
  1068.  * both digging and falling.
  1069.  */
  1070. boolean
  1071. Can_fall_thru(lev)
  1072. d_level *lev;
  1073. {
  1074.     return Can_dig_down(lev) || Is_stronghold(lev);
  1075. }
  1076.  
  1077. /*
  1078.  * True if one can rise up a level (e.g. cursed gain level).
  1079.  * This happens on intermediate dungeon levels or on any top dungeon
  1080.  * level that has a stairwell style branch to the next higher dungeon.
  1081.  * Checks for amulets and such must be done elsewhere.
  1082.  */
  1083. boolean
  1084. Can_rise_up(lev)
  1085. d_level *lev;
  1086. {
  1087.     return !In_endgame(lev) &&
  1088.     (lev->dlevel > 1 ||
  1089.      (dungeons[lev->dnum].entry_lev == 1 && ledger_no(lev) != 1 &&
  1090.       sstairs.sx && sstairs.up));
  1091. }
  1092.  
  1093. /*
  1094.  * It is expected that the second argument of get_level is a depth value,
  1095.  * either supplied by the user (teleport control) or randomly generated.
  1096.  * But more than one level can be at the same depth.  If the target level
  1097.  * is "above" the present depth location, get_level must trace "up" from
  1098.  * the player's location (through the ancestors dungeons) the dungeon
  1099.  * within which the target level is located.  With only one exception
  1100.  * which does not pass through this routine (see level_tele), teleporting
  1101.  * "down" is confined to the current dungeon.  At present, level teleport
  1102.  * in dungeons that build up is confined within them.
  1103.  */
  1104. void
  1105. get_level(newlevel, levnum)
  1106. d_level *newlevel;
  1107. int levnum;
  1108. {
  1109.     branch *br;
  1110.     xchar dgn = u.uz.dnum;
  1111.  
  1112.     if (levnum <= 0) {
  1113.         impossible("get_level:  levnum = %d\n", levnum);
  1114.         levnum = u.uz.dlevel;
  1115.     } else if (levnum > dungeons[dgn].depth_start
  1116.                 + dungeons[dgn].num_dunlevs - 1) {
  1117.         /* beyond end of dungeon, jump to last level */
  1118.         levnum = dungeons[dgn].num_dunlevs;
  1119.     } else {
  1120.         /* The desired level is in this dungeon or a "higher" one. */
  1121.  
  1122.         /*
  1123.          * Branch up the tree until we reach a dungeon that contains the
  1124.          * levnum.
  1125.          */
  1126.         if (levnum < dungeons[dgn].depth_start) {
  1127.  
  1128.         do {
  1129.             /*
  1130.              * Find the parent dungeon of this dungeon.
  1131.              *
  1132.              * This assumes that end2 is always the "child" and it is
  1133.              * unique.
  1134.              */
  1135.             for (br = branches; br; br = br->next)
  1136.             if (br->end2.dnum == dgn) break;
  1137.             if (!br)
  1138.             panic("get_level: can't find parent dungeon");
  1139.  
  1140.             dgn = br->end1.dnum;
  1141.         } while (levnum < dungeons[dgn].depth_start);
  1142.         }
  1143.  
  1144.         /* We're within the same dungeon; calculate the level. */
  1145.         levnum = levnum - dungeons[dgn].depth_start + 1;
  1146.     }
  1147.  
  1148.     newlevel->dnum = dgn;
  1149.     newlevel->dlevel = levnum;
  1150. }
  1151.  
  1152. #endif /* OVL1 */
  1153. #ifdef OVL0
  1154.  
  1155. #ifdef MULDGN
  1156. boolean
  1157. In_quest(lev)    /* are you in the quest dungeon? */
  1158. d_level *lev;
  1159. {
  1160.     return(lev->dnum == quest_dnum);
  1161. }
  1162. #endif /* MULDGN */
  1163.  
  1164. #endif /* OVL0 */
  1165. #ifdef OVL1
  1166.  
  1167. #ifdef MULDGN
  1168. boolean
  1169. In_mines(lev)    /* are you in the mines dungeon? */
  1170. d_level    *lev;
  1171. {
  1172.     return(lev->dnum == mines_dnum);
  1173. }
  1174.  
  1175. /*
  1176.  * Return the branch for the given dungeon.
  1177.  *
  1178.  * This function assumes:
  1179.  *    + This is not called with "Dungeons of Doom".
  1180.  *    + There is only _one_ branch to a given dungeon.
  1181.  *    + Field end2 is the "child" dungeon.
  1182.  */
  1183. branch *
  1184. dungeon_branch(s)
  1185.     const char *s;
  1186. {
  1187.     branch *br;
  1188.     xchar  dnum;
  1189.  
  1190.     dnum = dname_to_dnum(s);
  1191.  
  1192.     /* Find the branch that connects to dungeon i's branch. */
  1193.     for (br = branches; br; br = br->next)
  1194.     if (br->end2.dnum == dnum) break;
  1195.  
  1196.     if (!br) panic("dgn_entrance: can't find entrance to %s", s);
  1197.  
  1198.     return br;
  1199. }
  1200.  
  1201. /*
  1202.  * This returns true if the hero is on the same level as the entrance to
  1203.  * the named dungeon.
  1204.  *
  1205.  * Called from do.c and mklev.c.
  1206.  *
  1207.  * Assumes that end1 is always the "parent".
  1208.  */
  1209. boolean
  1210. at_dgn_entrance(s)
  1211.     const char *s;
  1212. {
  1213.     branch *br;
  1214.  
  1215.     br = dungeon_branch(s);
  1216.     return on_level(&u.uz, &br->end1) ? TRUE : FALSE;
  1217. }
  1218. #endif /* MULDGN */
  1219.  
  1220. boolean
  1221. In_tower(lev)    /* are you inside the tower? */
  1222. d_level    *lev;
  1223. {
  1224.     return(lev->dnum == tower_dnum);
  1225. }
  1226.  
  1227. #endif /* OVL1 */
  1228. #ifdef OVL0
  1229.  
  1230. boolean
  1231. In_hell(lev)    /* are you in one of the Hell levels? */
  1232. d_level    *lev;
  1233. {
  1234.     return(dungeons[lev->dnum].flags.hellish);
  1235. }
  1236.  
  1237. #endif /* OVL0 */
  1238. #ifdef OVL1
  1239.  
  1240. void
  1241. goto_hell(at_stairs, falling)    /* go directly to hell... */
  1242. boolean    at_stairs, falling;
  1243. {
  1244.     d_level lev;
  1245.  
  1246.     lev.dnum = wiz1_level.dnum;
  1247.     lev.dlevel = 1;
  1248.     goto_level(&lev, at_stairs, falling, FALSE);
  1249. }
  1250.  
  1251. void
  1252. assign_level(dest, src)        /* equivalent to dest = source */
  1253. d_level    *dest, *src;
  1254. {
  1255.     dest->dnum = src->dnum;
  1256.     dest->dlevel = src->dlevel;
  1257. }
  1258.  
  1259. void
  1260. assign_rnd_level(dest, src, range)    /* dest = src + rn1(range) */
  1261. d_level    *dest, *src;
  1262. int range;
  1263. {
  1264.     dest->dnum = src->dnum;
  1265.     dest->dlevel = src->dlevel + ((range > 0) ? rnd(range) : -rnd(-range)) ;
  1266.  
  1267.     if(dest->dlevel > dunlevs_in_dungeon(dest))
  1268.         dest->dlevel = dunlevs_in_dungeon(dest);
  1269.     else if(dest->dlevel < 1)
  1270.         dest->dlevel = 1;
  1271. }
  1272.  
  1273. #endif /* OVL1 */
  1274. #ifdef OVL0
  1275.  
  1276. int
  1277. induced_align(pct)
  1278. int    pct;
  1279. {
  1280.     s_level    *lev = Is_special(&u.uz);
  1281.     aligntyp al;
  1282.  
  1283.     if (lev && lev->flags.align)
  1284.         if(rn2(100) < pct) return(lev->flags.align);
  1285.  
  1286.     if(dungeons[u.uz.dnum].flags.align)
  1287.         if(rn2(100) < pct) return(dungeons[u.uz.dnum].flags.align);
  1288.  
  1289.     al = rn2(3) - 1;
  1290.     return(Align2amask(al));
  1291. }
  1292.  
  1293. #endif /* OVL0 */
  1294. #ifdef OVL1
  1295.  
  1296. boolean
  1297. Invocation_lev(lev)
  1298. d_level *lev;
  1299. {
  1300.     return(In_hell(lev) &&
  1301.         lev->dlevel == (dungeons[lev->dnum].num_dunlevs - 1));
  1302. }
  1303.  
  1304. /* use instead of depth() wherever a degree of difficulty is made
  1305.  * dependent on the location in the dungeon (eg. monster creation).
  1306.  */
  1307. xchar
  1308. level_difficulty()
  1309. {
  1310.     if (In_endgame(&u.uz))
  1311.         return(depth(&sanctum_level) + u.ulevel/2);
  1312.     else
  1313.         if (u.uhave.amulet)
  1314.             return(deepest_lev_reached(FALSE));
  1315.         else
  1316.             return(depth(&u.uz));
  1317. }
  1318.  
  1319.  
  1320. #ifdef WIZARD
  1321.  
  1322. /* Convert a branch type to a string usable by print_dungeon(). */
  1323. static const char *
  1324. br_string(type)
  1325.     int type;
  1326. {
  1327.     switch (type) {
  1328.     case BR_PORTAL:     return "Portal";
  1329.     case BR_NO_END1: return "Connection";
  1330.     case BR_NO_END2: return "One way stair";
  1331.     case BR_STAIR:     return "Stair";
  1332.     }
  1333.     return " (unknown)";
  1334. }
  1335.  
  1336. /* Print all child branches between the lower and upper bounds. */
  1337. static void
  1338. print_branch(win, dnum, lower_bound, upper_bound)
  1339.     winid win;
  1340.     int   dnum;
  1341.     int   lower_bound;
  1342.     int   upper_bound;
  1343. {
  1344.     branch *br;
  1345.     char buf[BUFSZ];
  1346.  
  1347.     /* This assumes that end1 is the "parent". */
  1348.     for (br = branches; br; br = br->next) {
  1349.     if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel &&
  1350.                     br->end1.dlevel <= upper_bound) {
  1351.         Sprintf(buf,"   %s to %s: %d",
  1352.             br_string(br->type),
  1353.             dungeons[br->end2.dnum].dname,
  1354.             depth(&br->end1));
  1355.         putstr(win, 0, buf);
  1356.     }
  1357.     }
  1358. }
  1359.  
  1360. /* Print available dungeon information. */
  1361. void
  1362. print_dungeon()
  1363. {
  1364.     int     i, last_level, nlev;
  1365.     char    buf[BUFSZ];
  1366.     boolean first;
  1367.     s_level *slev;
  1368.     dungeon *dptr;
  1369.     branch  *br;
  1370.     winid   win = create_nhwindow(NHW_MENU);
  1371.  
  1372.     for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) {
  1373.     nlev = dptr->num_dunlevs;
  1374.     if (nlev > 1)
  1375.         Sprintf(buf, "%s: levels %d to %d", dptr->dname, dptr->depth_start,
  1376.                         dptr->depth_start + nlev - 1);
  1377.     else
  1378.         Sprintf(buf, "%s: level %d", dptr->dname, dptr->depth_start);
  1379.  
  1380.     /* Most entrances are uninteresting. */
  1381.     if (dptr->entry_lev != 1) {
  1382.         if (dptr->entry_lev == nlev)
  1383.         Strcat(buf, ", entrance from below");
  1384.         else
  1385.         Sprintf(eos(buf), ", entrance on %d",
  1386.             dptr->depth_start + dptr->entry_lev - 1);
  1387.     }
  1388.     putstr(win, 0, buf);
  1389.  
  1390.     /*
  1391.      * Circle through the special levels to find levels that are in
  1392.      * this dungeon.
  1393.      */
  1394.     for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) {
  1395.         if (slev->dlevel.dnum != i) continue;
  1396.  
  1397.         /* print any branches before this level */
  1398.         print_branch(win, i, last_level, slev->dlevel.dlevel);
  1399.  
  1400.         Sprintf(buf, "   %s: %d", slev->proto, depth(&slev->dlevel));
  1401.         if (Is_stronghold(&slev->dlevel))
  1402.         Sprintf(eos(buf), " (tune %s)", tune);
  1403.         putstr(win, 0, buf);
  1404.  
  1405.         last_level = slev->dlevel.dlevel;
  1406.     }
  1407.     /* print branches after the last special level */
  1408.     print_branch(win, i, last_level, MAXLEVEL);
  1409.     }
  1410.  
  1411.     /* Print out floating branches (if any). */
  1412.     for (first = TRUE, br = branches; br; br = br->next) {
  1413.     if (br->end1.dnum == n_dgns) {
  1414.         if (first) {
  1415.         putstr(win, 0, "");
  1416.         putstr(win, 0, "Floating branches");
  1417.         first = FALSE;
  1418.         }
  1419.         Sprintf(buf, "   %s to %s",
  1420.             br_string(br->type), dungeons[br->end2.dnum].dname);
  1421.         putstr(win, 0, buf);
  1422.     }
  1423.     }
  1424.  
  1425.     /* I hate searching for the invocation pos while debugging. -dean */
  1426.     if (Invocation_lev(&u.uz)) {
  1427.     putstr(win, 0, "");
  1428.     Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)",
  1429.         inv_pos.x, inv_pos.y, u.ux, u.uy);
  1430.     putstr(win, 0, buf);
  1431.     }
  1432.     /*
  1433.      * The following is based on the assumption that the inter-level portals
  1434.      * created by the level compiler (not the dungeon compiler) only exist
  1435.      * one per level (currently true, of course).
  1436.      */
  1437.     else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
  1438.                 || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)) {
  1439.     struct trap *trap;
  1440.     for (trap = ftrap; trap; trap = trap->ntrap)
  1441.         if (trap->ttyp == MAGIC_PORTAL) break;
  1442.  
  1443.     putstr(win, 0, "");
  1444.     if (trap)
  1445.         Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)",
  1446.         trap->tx, trap->ty, u.ux, u.uy);
  1447.     else
  1448.         Sprintf(buf, "No portal found.");
  1449.     putstr(win, 0, buf);
  1450.     }
  1451.  
  1452.     display_nhwindow(win, TRUE);
  1453.     destroy_nhwindow(win);
  1454. }
  1455.  
  1456. #endif /* WIZARD */
  1457. #endif /* OVL1 */
  1458.  
  1459. /*dungeon.c*/
  1460.